package gestionOrdres;

import java.util.List;

import com.hp.hpl.jena.rdf.model.Property;
import com.hp.hpl.jena.rdf.model.RDFWriter;
import com.hp.hpl.jena.rdf.model.Resource;

import metiers.Axe;
import metiers.Concept;
import metiers.typeAssociationConcept;

/**
 * La classe mise à jour permet la mise à jour du fichier de données de
 * l'ontologie de contexte. Elle a deux attributs:
 * <ul>
 * <li>lectureOrdre de type LectureFichierOrdre</li>
 * <li>lectureCsv de type LectureCsv</li>
 * </ul>
 * La mise à jou se fait par l'appel de la fonction mettre à jour
 * 
 * @see LectureFichierOrdre
 * @see LectureCsv
 * @author Freddy KAKOU
 * 
 */

public class MiseAjour {

	private LectureFichierOrdre lectureOrdre;
	private LectureCsv lectureCsv;

	/**
	 * le constructeur de la classe
	 * */
	public MiseAjour() {

		lectureOrdre = LectureFichierOrdre.getUniqueLecture();
		lectureCsv = new LectureCsv();
	}

	/**
	 * Ctte méthode mets à jour les concepts et les axes de l'unique instance
	 * LectureFichierOrdre.<br/>
	 * 
	 */
	public void mettreAjour() {

		mettreAjourConcepts();
		mettreAjourAxe();
	}

	/**
	 * Mise à jour des axes Pour tous les axes de lectureCsv on vérifie s'ils
	 * existent déjà dans lectureOrdre. Si oui on modifie les valeurs leurs
	 * attributs dans lectureOrdre. Si non on les ajoute dans lectureOrdre.
	 */
	private void mettreAjourAxe() {

		int l1 = lectureOrdre.getListeAxes().size();
		int l2 = lectureCsv.getOntologieContext().size();

		if (l1 == 0) {
			for (int i = 0; i < l2; i++) {
				Axe axeCsv = lectureCsv.getOntologieContext().get(i);
				ajouterAsso(lectureOrdre.getListeAxes(), axeCsv);
			}
		} else {
			for (int i = 0; i < l2; i++) {
				Axe axeCsv = lectureCsv.getOntologieContext().get(i);

				for (int j = 0; j < l1; j++) {
					Axe axeXml = lectureOrdre.getListeAxes().get(j);

					if (axeCsv.egaliteAsso(axeXml)) {

						// on met à jour le nombre de requête

						if (axeCsv.getTypeAssociation().equals(
								typeAssociationConcept.Principal)) {

							int nv_efftotPrin = axeCsv.getConcept()
									.getEffectifTotalPrinc()
									+ axeXml.getConcept()
											.getEffectifTotalPrinc();

							double nouvelleStat;
							nouvelleStat = ((axeCsv.getConcept()
									.getEffectifTotalPrinc() * axeCsv
									.getStatistiqueX2()) + (axeXml.getConcept()
									.getEffectifTotalPrinc() * axeXml
									.getStatistiqueX2()))
									/ nv_efftotPrin;

							// System.out.println("(" + axeCsv.getConcept()
							// .getEffectifTotalPrinc() + "*" + axeCsv
							// .getStatistiqueX2() + "+" + axeXml.getConcept()
							// .getEffectifTotalPrinc() + "*" + axeXml
							// .getStatistiqueX2() + ")"
							// + "/" + nv_efftotPrin);

							axeXml.setStatistiqueX2(nouvelleStat);

						} else {
							int nv_efftotComp = axeCsv.getConcept()
									.getEffectifTotalComp()
									+ axeXml.getConcept()
											.getEffectifTotalComp();

							// System.out.println(axeCsv.getConcept()
							// .getEffectifTotalComp() +
							// "+" + axeXml.getConcept()
							// .getEffectifTotalComp());

							double nouvelleStat;
							nouvelleStat = ((axeCsv.getConcept()
									.getEffectifTotalComp() * axeCsv
									.getStatistiqueX2()) + (axeXml.getConcept()
									.getEffectifTotalComp() * axeXml
									.getStatistiqueX2()))
									/ nv_efftotComp;

							axeXml.setStatistiqueX2(nouvelleStat);

							// System.out.println("(" + axeCsv.getConcept()
							// .getEffectifTotalComp() + "*" + axeCsv
							// .getStatistiqueX2() + "+" + axeXml.getConcept()
							// .getEffectifTotalComp() + "*" + axeXml
							// .getStatistiqueX2() + ")"
							// + "/" + nv_efftotComp);

						}

					} else {
						ajouterAsso(lectureOrdre.getListeAxes(), axeCsv);
						// list1.add(ass);
					}

				}
			}
		}
	}

	/**
	 * Mise à jour des concepts Pour tous les concepts de lectureCsv on vérifie
	 * s'il existe déjà dans lectureOrdre. Si oui on modifie les valeurs leurs
	 * attributs dans lectureOrdre. Si non on les ajoute dans lectureOrdre.
	 */
	private void mettreAjourConcepts() {

		if (lectureOrdre.getListeConcepts().size() == 0) {

			lectureOrdre.getListeConcepts().addAll(
					lectureCsv.getListContextConcept());

		} else {

			for (int i = 0; i < lectureCsv.getListContextConcept().size(); i++) {

				if (lectureOrdre.getListeConcepts().contains(
						lectureCsv.getListContextConcept().get(i))) {
					int index = lectureCsv.getListContextConcept().indexOf(
							lectureCsv.getListContextConcept().get(i));
					
					
					lectureOrdre.getListeConcepts().get(index)
							.setNombreRequetes(
									lectureOrdre.getListeConcepts().get(index)
											.getNombreRequetes() + 1);
					
					lectureOrdre.getListeConcepts().get(index)
							.setEffectifTotalPrinc(
									lectureOrdre.getListeConcepts().get(index)
											.getEffectifTotalPrinc()
											+ lectureCsv
													.getListContextConcept()
													.get(i)
													.getEffectifTotalPrinc());
					
					lectureOrdre.getListeConcepts().get(index)
							.setEffectifTotalComp(
									lectureOrdre.getListeConcepts().get(index)
											.getEffectifTotalComp()
											+ lectureCsv
													.getListContextConcept()
													.get(i)
													.getEffectifTotalComp());
				}
				
				else {
					lectureOrdre.getListeConcepts().add(
							lectureCsv.getListContextConcept().get(i));
				}
				

			}
		}
	}

	/**
	 * Ajout d'un concept
	 * 
	 * @param c
	 */
	public void ajoutetConcept(Concept c) {

		if (lectureOrdre.getListeConcepts().size() != 0) {
			boolean p = false;

			for (int i = 0; i < lectureOrdre.getListeConcepts().size(); i++) {
				if (lectureOrdre.getListeConcepts().get(i).equals(c)) {
					p = true;
				}
			}
			if (p != true) {
				lectureOrdre.getListeConcepts().add(c);
			}
		} else {
			lectureOrdre.getListeConcepts().add(c);
		}
	}

	/**
	 * ajoute un axe à une liste d'axe en vérifiant ce ce axe<br/>
	 * n'existe pas déjà dans la liste.
	 * 
	 * @param l
	 * @param ass
	 */
	public static void ajouterAsso(List<Axe> l, Axe ass) {

		int p = l.size();
		if (l.size() == 0) {
			l.add(ass);
		} else {

			boolean e = false;
			for (int i = 0; i < p; i++) {

				if (l.get(i).egaliteAsso(ass)) {
					e = true;
				}

			}
			if (e == false) {
				l.add(ass);
			}
		}
	}

	/**
	 * Cette fonction permet d'écrire dans le fichier de l'ontologie. Elle
	 * utilise la librairie JENA.
	 */
	public void ecriture() {

		lectureOrdre.getDonnees().removeAll();
		
		// on crée les types axe et concept
		Resource concept = lectureOrdre.getDonnees().createResource(
				"http://onthologieContextePFE.owl#Concept");
		Resource axe = lectureOrdre.getDonnees().createResource(
				"http://onthologieContextePFE.owl#Axe");
		
		String rdf = "http://www.w3.org/1999/02/22-rdf-syntax-ns#";
		Property propType = lectureOrdre.getDonnees().createProperty(rdf + "type");

		// création des concepts
		// poour cela on parcours la liste de concepts de lectureOrdre
		// on s'assure qu'elle n'est pas vide
		if (lectureOrdre.getListeConcepts().size() != 0) {
			
			
			System.out.println("taille de la liste de concepts " + lectureOrdre.getListeConcepts().size());
			
			
			// On crée les conceptes
			for (int i = 0; i < lectureOrdre.getListeConcepts().size(); i++) {
				
				
				
				/* création et ajout du concept */
				String concepturi1 = "http://onthologieContextePFE.owl#"
						+ lectureOrdre.getListeConcepts().get(i).getNom();
				long nbrRqt = lectureOrdre.getListeConcepts().get(i)
						.getNombreRequetes();
				long effTtlP = lectureOrdre.getListeConcepts().get(i)
						.getEffectifTotalPrinc();
				long effTtlC = lectureOrdre.getListeConcepts().get(i)
						.getEffectifTotalComp();

				// création de la ressource
				Resource c1 = lectureOrdre.getDonnees().createResource(
						concepturi1);
				lectureOrdre.getDonnees().add(c1, propType, concept);

				// ajout des données de la ressource au modèle
				lectureOrdre
						.getDonnees()
						.add(
								c1,
								lectureOrdre
										.getModel()
										.getProperty(
												"http://onthologieContextePFE.owl#nombreRequetes"),
												lectureOrdre
												.getDonnees().createTypedLiteral(nbrRqt));
				lectureOrdre
						.getDonnees()
						.add(
								c1,
								lectureOrdre
										.getModel()
										.getProperty(
												"http://onthologieContextePFE.owl#effectifTotalEnComplementaire"),
												lectureOrdre
												.getDonnees().createTypedLiteral(effTtlC));
				lectureOrdre
						.getDonnees()
						.add(
								c1,
								lectureOrdre
										.getModel()
										.getProperty(
												"http://onthologieContextePFE.owl#effectifTotalEnPrincipal"),
												lectureOrdre
												.getDonnees().createTypedLiteral(effTtlP));

			}
		}

		// Création des axes
		// on s'assure que la liste des axe n'est pas vide
		
		System.out.println("taille de la liste des axes " + lectureOrdre.getListeAxes().size());
		
		if (lectureOrdre.getListeAxes().size() != 0) {

			for (int i = 0; i < lectureOrdre.getListeAxes().size(); i++) {

				/* création et ajout de la ressource axe */
				// on definit l'URI de cette ressource ainsi que les valeurs
				// associées à cette ressource
				String concepturi = "http://onthologieContextePFE.owl#axe_"
						+ lectureOrdre.getListeAxes().get(i).getConcept()
								.getNom()
						+ "_"
						+ lectureOrdre.getListeAxes().get(i)
								.getConceptAssocie().getNom()
						+ "_en_"
						+ lectureOrdre.getListeAxes().get(i)
								.getTypeAssociation();
				int nbrValManq = lectureOrdre.getListeAxes().get(i).getNbrVal();
				int classement = lectureOrdre.getListeAxes().get(i)
						.getPourClassement();
				int nbrChoix = lectureOrdre.getListeAxes().get(i)
						.getNombreChoix();

				double aPourStatistiqueX2 = lectureOrdre.getListeAxes().get(i)
						.getStatistiqueX2();

				// if (((Double) aPourStatistiqueX2).isNaN()) {
				// System.out.println("Attention NaN");
				// }

				// on crée ainsi la ressource axe

				Resource axeuri = lectureOrdre.getDonnees().createResource(
						concepturi);
				lectureOrdre.getDonnees().add(axeuri, propType, axe);

				/* on récupère le concept associée à cet axe */
				/*---------------------------------------------DEBUT---------------------------------------------------------------------------------------------------*/
				Resource rst = lectureOrdre.getDonnees().getResource(
						"http://onthologieContextePFE.owl#"
								+ lectureOrdre.getListeAxes().get(i)
										.getConcept().getNom());
				
//				System.out.println("get property rst " + rst.getProperty(lectureOrdre
//						.getModel()
//						.getProperty(
//								"http://onthologieContextePFE.owl#effectifTotalEnComplementaire")).toString());

				// on cherche le type d'association
				if (lectureOrdre.getListeAxes().get(i).getTypeAssociation()
						.equals(typeAssociationConcept.Principal)) {
					// ajout de la ressource axe au modèle
					lectureOrdre
							.getDonnees()
							.add(
									rst,
									lectureOrdre
											.getModel()
											.getProperty(
													"http://onthologieContextePFE.owl#aPourAxeEnPrincipal"),
									axeuri);

				} else {
					lectureOrdre
							.getDonnees()
							.add(
									rst,
									lectureOrdre
											.getModel()
											.getProperty(
													"http://onthologieContextePFE.owl#aPourAxeEnComplementaire"),
									axeuri);

				}
				// on ajoute les propriétés de l'axe au model

				lectureOrdre
						.getDonnees()
						.add(
								axeuri,
								lectureOrdre
										.getModel()
										.getProperty(
												"http://onthologieContextePFE.owl#aPourClassement"),
												lectureOrdre
												.getDonnees().createTypedLiteral(classement));
				lectureOrdre
						.getDonnees()
						.add(
								axeuri,
								lectureOrdre
										.getModel()
										.getProperty(
												"http://onthologieContextePFE.owl#aNombreChoix"),
												lectureOrdre
												.getDonnees().createTypedLiteral(nbrChoix));
				lectureOrdre
						.getDonnees()
						.add(
								axeuri,
								lectureOrdre
										.getModel()
										.getProperty(
												"http://onthologieContextePFE.owl#aPourNombreValeursManquantes"),
												lectureOrdre
												.getDonnees().createTypedLiteral(nbrValManq));
				lectureOrdre
						.getDonnees()
						.add(
								axeuri,
								lectureOrdre
										.getModel()
										.getProperty(
												"http://onthologieContextePFE.owl#aPourStatistiqueX2"),
												lectureOrdre
												.getDonnees().createTypedLiteral(aPourStatistiqueX2));

				/*---------------------------------------FIN---------------------------------------------------------------------------------------------------------------*/

				// on récupère on ajoute le concept conerné par cet axe .
				Resource rst2 = lectureOrdre.getDonnees().getResource(
						"http://onthologieContextePFE.owl#"
								+ lectureOrdre.getListeAxes().get(i)
										.getConceptAssocie().getNom());
				
//				System.out.println("get property rst2 " + rst2.getProperty(lectureOrdre
//						.getModel()
//						.getProperty(
//								"http://onthologieContextePFE.owl#effectifTotalEnComplementaire")).toString());
//				
				lectureOrdre
						.getDonnees()
						.add(
								axeuri,
								lectureOrdre
										.getModel()
										.getProperty(
												"http://onthologieContextePFE.owl#aPourConceptConcerne"),
								rst2);

			}

		}
		
			
		/* lecture et écriture dans le fichier de données */
		RDFWriter w = lectureOrdre.getDonnees().getWriter("RDF/XML-ABBREV");
		w.setProperty("attributeQuoteChar", "'");
		w.setProperty("showXMLDeclaration", "true");
		w.setProperty("tab", "1");
		w
				.setProperty(
						"blockRules",
						"daml:collection,parseTypeLiteralPropertyElt,"
								+ "parseTypeResourcePropertyElt,parseTypeCollectionPropertyElt");
		EcritureFichier lect = new EcritureFichier(System
				.getProperty("pfe.fichierOntologie.dir"),
				"donneesCourantes.xml");
		w.write(lectureOrdre.getDonnees(), lect.getFlux(), "RDF/XML-ABBREV");

	}

	public LectureFichierOrdre getLectureOrdre() {
		return lectureOrdre;
	}

	public void setLectureOrdre(LectureFichierOrdre lectureOrdre) {
		this.lectureOrdre = lectureOrdre;
	}

	public LectureCsv getLectureCsv() {
		return lectureCsv;
	}

	public void setLectureCsv(LectureCsv lectureCsv) {
		this.lectureCsv = lectureCsv;
	}
}